<?php
# http://projects:8081/cdapp-2kt-api/api/activity_notam_load.php

include_once './_portal.php';
include_once './request_sipds.php';

const FAKE = false;

const MIN_TTL = 600 * 1000;
const MAX_TTL = 1200 * 1000;
const PARAM_NAME = 'activityNOTAMRefreshTime';
const API_NAME = [
  'notamWebService.findNotamByfilterSql.ZUTF',
  'notamWebService.findNotamByfilterSql.ZUUU',
  'notamWebService.findNotamByfilterSql.ZUMY',
  'notamWebService.findNotamByfilterSql.ZULZ',
  'notamWebService.findNotamByfilterSql.ZUYB',
];
const MONTH_STRINGS = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];

$force = isset($_GET['force']) ? $_GET['force'] : 0;
$refresh_info = get_param(PARAM_NAME);

if ($refresh_info) {
  $ttl_verify = verify_ttl($refresh_info['tx'], $refresh_info['rx'], MIN_TTL, MAX_TTL);
  $info = 'Load NOTAM ' . $ttl_verify['info'];
  $status = $ttl_verify['status'];
  $time = $ttl_verify['time'];
  $version = isset($refresh_info['version']) ? $refresh_info['version'] : $refresh_info['rx'];
  if ($status > 0 || $force == 1) {
    save_param(PARAM_NAME, [
      'tx' => $time,
      'rx' => $refresh_info['rx'],
      'version' => $refresh_info['version'],
    ]);
    $result = main();
    if ($result['success'] && $result['count']['total'] > 0) {
      $version = timestamp();
      save_param(PARAM_NAME, [
        'tx' => $time,
        'rx' => timestamp(),
        'version' => $version,
      ]);
    }
    output(['message' => $force == 1 ? 'Forced load NOTAM' : $info, 'result' => $result]);
  } else {
    output(['message' => $info, 'result' => null]);
  }
} else {
  save_param(PARAM_NAME, [
    'tx' => timestamp(),
    'rx' => timestamp() - 1,
    'version' => timestamp() - 1,
  ]);
  $result = main();
  if ($result['success'] && $result['count']['total'] > 0) {
    $version = timestamp();
    save_param(PARAM_NAME, [
      'tx' => timestamp(),
      'rx' => timestamp(),
      'version' => $version,
    ]);
  }
  output(['message' => 'initialized', 'result' => $result]);
}

function main() {
  $t0 = timestamp();
  $fake_file_path = './activity_notam_load.json';
  $fake_data = json_parse(file_get_contents($fake_file_path));
  $response_zutf = FAKE ? $fake_data['ZUTF'] : request_sipds(API_NAME[0]);
  $response_zuuu = FAKE ? $fake_data['ZUUU'] : request_sipds(API_NAME[1]);
  $response_zumy = FAKE ? $fake_data['ZUMY'] : request_sipds(API_NAME[2]);
  $response_zulz = FAKE ? $fake_data['ZULZ'] : request_sipds(API_NAME[3]);
  $response_zuyb = FAKE ? $fake_data['ZUYB'] : request_sipds(API_NAME[4]);
  if (!FAKE) {
    $fake_data = ['ZUTF' => $response_zutf, 'ZUUU' => $response_zuuu, 'ZUMY' => $response_zumy];
  }
  $cancelled_array = [];
  $count = 0;
  $sql_array = [];
  $t1 = timestamp();

  # process response_zutf
  if (isset($response_zutf['data']['CONTENTS']) && count($response_zutf['data']['CONTENTS']) > 0) {
    foreach ($response_zutf['data']['CONTENTS'] as $notam) {
      $count++;
      $notam['TELEXTYPE'] == 'NOTAMN' ? null : $cancelled_array[] = $notam['REPLCNLNTMNO'];
      $sql = fetch_sql($notam);
      $sql == null ? null : $sql_array[] = $sql;
    }
  }

  # process response_zuuu
  if (isset($response_zuuu['data']['CONTENTS']) && count($response_zuuu['data']['CONTENTS']) > 0) {
    foreach ($response_zuuu['data']['CONTENTS'] as $notam) {
      $count++;
      $notam['TELEXTYPE'] == 'NOTAMN' ? null : $cancelled_array[] = $notam['REPLCNLNTMNO'];
      $sql = fetch_sql($notam);
      $sql == null ? null : $sql_array[] = $sql;
    }
  }

  # process response_zumy
  if (isset($response_zumy['data']['CONTENTS']) && count($response_zumy['data']['CONTENTS']) > 0) {
    foreach ($response_zumy['data']['CONTENTS'] as $notam) {
      $count++;
      $notam['TELEXTYPE'] == 'NOTAMN' ? null : $cancelled_array[] = $notam['REPLCNLNTMNO'];
      $sql = fetch_sql($notam);
      $sql == null ? null : $sql_array[] = $sql;
    }
  }

  # process response_zulz
  if (isset($response_zulz['data']['CONTENTS']) && count($response_zulz['data']['CONTENTS']) > 0) {
    foreach ($response_zulz['data']['CONTENTS'] as $notam) {
      $count++;
      $notam['TELEXTYPE'] == 'NOTAMN' ? null : $cancelled_array[] = $notam['REPLCNLNTMNO'];
      $sql = fetch_sql($notam);
      $sql == null ? null : $sql_array[] = $sql;
    }
  }

  # process response_zuyb
  if (isset($response_zuyb['data']['CONTENTS']) && count($response_zuyb['data']['CONTENTS']) > 0) {
    foreach ($response_zuyb['data']['CONTENTS'] as $notam) {
      $count++;
      $notam['TELEXTYPE'] == 'NOTAMN' ? null : $cancelled_array[] = $notam['REPLCNLNTMNO'];
      $sql = fetch_sql($notam);
      $sql == null ? null : $sql_array[] = $sql;
    }
  }

  # return due to null response
  if ($count == 0) {
    $t2 = timestamp();
    return [
      'success' => true,
      'count' => [
        'total' => 0,
        'insert' => 0,
      ],
      'duration' => [
        'total' => $t2 - $t0,
        'response' => $t1 - $t0,
        'fetch' => $t2 - $t1,
      ],
    ];
  }

  # store response in file
  # disposed
  // if (!FAKE) {
  //   file_put_contents($fake_file_path, json_encode($fake_data));
  // }

  # process calcelled list
  $count_sql = count($sql_array);
  $cancelled_str = "'" . implode("','", $cancelled_array) . "'";
  $sql = "UPDATE `2kt_notam_record` SET `cancelled`= 1 WHERE `number` IN ({$cancelled_str})";
  $sql_array[] = $sql;
  $result = exec_sql_array($sql_array);
  $t2 = timestamp();
  return [
    'success' => true,
    'count' => [
      'total' => $count,
      'insert' => $count_sql,
    ],
    'duration' => [
      'total' => $t2 - $t0,
      'response' => $t1 - $t0,
      'fetch' => $t2 - $t1,
    ],
  ];
}

function fetch_sql($notam) {
  $expiration_time = isset($notam['ITEMCDATE']) ? date('Y-m-d H:i:s', strtotime($notam['ITEMCDATE'])) : (isset($notam['ITEMCAUX']) ? '2099-12-31 23:59:59' : '1900-01-01 00:00:00');
  // $expiration_time = isset($notam['ITEMCDATE']) ? (substr($notam['ITEMCDATE'], 0, 10)+' '+substr($notam['ITEMCDATE'], 10, 8)) : (isset($notam['ITEMCAUX']) ? '2099-12-31 23:59:59' : '1900-01-01 00:00:00');
  if ((time() - strtotime($expiration_time)) > (3 * 24 * 3600)) {
    return null;
  }
  $effective_time = date('Y-m-d H:i:s', strtotime($notam['ITEMBDATE']));
  // $effective_time = substr($notam['ITEMBDATE'], 0, 10)+' '+substr($notam['ITEMBDATE'], 10, 8);
  if (isset($notam['ITEME'])) {
    $notam['ITEME'] = str_replace("'", "＂", $notam['ITEME']);
    $notam['ITEME'] = str_replace("\r", "", $notam['ITEME']);
    $notam['ITEME'] = str_replace("\n\n", "\n", $notam['ITEME']);
    $notam['ITEME'] = trim($notam['ITEME']);
    $notam['ITEME'] = str_replace("\n", '\n', $notam['ITEME']);
  }
  $number = $notam['NOTAMSERIES'] . $notam['NOTAMNOPART1'] . '/' . $notam['NOTAMNOPART2'];
  $type = $notam['TELEXTYPE'];
  $airport = $notam['ITEMA'];
  $time_slots = isset($notam['ITEMD']) ? json_stringify(fetch_item_d($notam['ITEMD'], $effective_time, $expiration_time)) : '[]';
  $cancelled = 0;
  $text = marge_notam($notam);
  $origion = json_stringify($notam);
  $remarks = '';
  $sql = "REPLACE INTO `2kt_notam_record`(`number`, `type`, `airport`, `effectiveTime`, `expirationTime`, `timeSlots`, `cancelled`, `text`, `origion`, `remarks`) VALUES ('{$number}','{$type}','{$airport}','{$effective_time}','{$expiration_time}','{$time_slots}',{$cancelled},'{$text}','{$origion}','{$remarks}')";
  return $sql;
}

function marge_notam($notam) {
  // line 0
  $string = $notam['NOTAMSERIES'] . $notam['NOTAMNOPART1'] . '/' . $notam['NOTAMNOPART2'] . ' ' . $notam['TELEXTYPE'];
  $string .= $notam['TELEXTYPE'] == 'NOTAMN' ? "\n" : (' ' . $notam['REPLCNLNTMNO'] . "\n");

  // line 1
  $elem_FIR = isset($notam['ITEMQ']) ? $notam['ITEMQ'] : '';
  $elem_CODE = isset($notam['QCODE']) ? $notam['QCODE'] : '';
  $elem_TRAFFIC = isset($notam['TRAFFIC']) ? $notam['TRAFFIC'] : '';
  $elem_PURPOSE = isset($notam['PURPOSE']) ? $notam['PURPOSE'] : '';
  $elem_SCOPE = isset($notam['RANGE']) ? $notam['RANGE'] : '';
  $elem_LOWER = isset($notam['LOWER']) ? $notam['LOWER'] : '';
  $elem_UPPER = isset($notam['UPPER']) ? $notam['UPPER'] : '';
  $elem_POSITION = isset($notam['LATITUDE']) ? $notam['LATITUDE'] : '';
  $elem_POSITION .= isset($notam['NORS']) ? $notam['NORS'] : '';
  $elem_POSITION .= isset($notam['LONGITUDE']) ? $notam['LONGITUDE'] : '';
  $elem_POSITION .= isset($notam['EORW']) ? $notam['EORW'] : '';
  $elem_POSITION .= isset($notam['RADIUS']) ? $notam['RADIUS'] : '';
  $string .= "Q) {$elem_FIR}/{$elem_CODE}/{$elem_TRAFFIC}/{$elem_PURPOSE}/{$elem_SCOPE}/{$elem_LOWER}/{$elem_UPPER}/{$elem_POSITION}\n";
  // line 2
  $string .= "A) {$notam['ITEMA']} B) {$notam['ITEMB']}";
  $string .= isset($notam['ITEMC']) ? (' C) ' . $notam['ITEMC']) : '';
  $string .= isset($notam['ITEMCAUX']) ? (' C) ' . $notam['ITEMCAUX']) : '';
  $string .= "\n";
  // line 3
  if (isset($notam['ITEMD'])) {
    $string .= "D) {$notam['ITEMD']}\n";
  }
  // line 4
  if (isset($notam['ITEME'])) {
    $string .= "E) {$notam['ITEME']}\n";
  }
  return $string;
}

function fetch_item_d($item_d, $item_b = '', $item_c = '') {

  # fetch time from item D
  $preg_count = preg_match_all('/\d\d\d\d-\d\d\d\d/', $item_d, $match);
  $times = [];
  // $preg_count: 匹配次数, 若为 0 或者 false 则不判断 $match 内容
  // @2024/06/21
  $matched_string = $preg_count ? $match[0][0] : '';
  if (strlen($matched_string) != 9) {
    return null;
  } else {
    $times['start'] = substr($match[0][0], 0, 2) . ':' . substr($match[0][0], 2, 2) . ':00';
    $times['end'] = substr($match[0][0], 5, 2) . ':' . substr($match[0][0], 7, 2) . ':00';
  }

  # fetch date from item D
  # ZUMY satuation: replace () with space
  $item_d = str_replace('(', ' ', $item_d);
  $item_d = str_replace(')', ' ', $item_d);
  $item_d = str_replace('  ', ' ', $item_d);
  /*
  C0017/24 NOTAMN
  Q)ZPKM/QMRLC/IV/NBO/A/000/999/3126N10444E005
  A)ZUMY B)2401052330 C)2401300600
  D)2330-0600(NEXT DAY)DLY
  E)RWY14/32 关闭,因施工.
   */
  $item_d_arr = explode(" ", $item_d);
  $beg_timestamp = strtotime($item_b);
  $end_timestamp = strtotime($item_c);
  if (in_array('EVERY', $item_d_arr)) {
    # EVERY satuation

    /*
    C5255/2023 NOTAMN
    Q) ZPKM/MRLC/IV/NBO/A/000/999/3035N10357E005
    A) ZUUU B) 2309040200 C) 2401310600
    D) 0200-0600 EVERY MON AND WED
    E) RWY02R/20L 关闭.
     */
    $matches = [];
    while ($beg_timestamp <= $end_timestamp) {
      $week = strtoupper(date("D", $beg_timestamp));
      if (in_array($week, $item_d_arr)) {
        $date = date('Y-m-d', $beg_timestamp);
        $matches[] = ['start' => $date . ' ' . (isset($times['start']) ? $times['start'] : '00:00:00'), 'end' => $date . ' ' . (isset($times['end']) ? $times['end'] : '23:59:59')];
      }
      $beg_timestamp += 24 * 3600;
    }
    return $matches;
  } elseif (in_array('DLY', $item_d_arr)) {
    # DLY satuation
    $matches = [];
    while ($beg_timestamp <= $end_timestamp) {
      $date_start = date('Y-m-d', $beg_timestamp);
      $is_next_day = (in_array('NEXT', $item_d_arr) && in_array('DAY', $item_d_arr)) || (strtotime($date_start . ' ' . $times['start']) > strtotime($date_start . ' ' . $times['end']));
      $date_end = $is_next_day ? date('Y-m-d', $beg_timestamp + 24 * 3600) : $date_start;
      $matches[] = ['start' => $date_start . ' ' . $times['start'], 'end' => $date_end . ' ' . $times['end']];
      $beg_timestamp += 24 * 3600;
    }
    return $matches;
  } else {
    # Normal satuation
    $matches = [];
    $month = -1;
    $day = -1;
    for ($i = 0; $i < count($item_d_arr); $i++) {
      if (is_numeric($item_d_arr[$i])) {
        $day = (int)$item_d_arr[$i];
      } else {
        $day = -1;
        //$month = -1;
        for ($k = 0; $k < count(MONTH_STRINGS); $k++) {
          if (MONTH_STRINGS[$k] == $item_d_arr[$i]) {
            $month = $k + 1;
          }
        }
      }
      if ($day !== -1) {
        // if missing month
        if ($month <= 0) {
          // day > beg_timestamp ? this month : next month
          if ($day >= date('d', $beg_timestamp)) {
            $month = date('m', $beg_timestamp);
          } else {
            $month = date('m', $end_timestamp);
          }
        }
        $date = substr($item_b, 0, 4) . '-' . $month . '-' . $day;
        // fix for next year
        if (strtotime($date . ' ' . $times['start']) < strtotime($item_b)) {
          $date = substr($item_c, 0, 4) . '-' . $month . '-' . $day;
        }
        $matches[] = ['start' => $date . ' ' . $times['start'], 'end' => $date . ' ' . $times['end']];
      }
    }
    logfile('activity_notam_load', json_stringify($matches));
    return $matches;
  }
}